﻿//-----------------------------------------------------------------------
// <copyright file="ActionExtensions.cs" author="Artak Mkrtchyan">
//     Creative Commons - GNU General Public License (http://creativecommons.org/licenses/GPL/2.0/
// </copyright>
// <author>Artak Mkrtchyan</author>
// <email>mkArtak@gmail.com</email>
// <date>15/07/2012</date>
//-----------------------------------------------------------------------
using System;
using System.Threading;

namespace ConsoleHoster.Common.Utilities
{
	public static class ActionExtensions
	{
		public static void SyncronizeCallByLocking(this Action argAction, object argLock, string argObjectName, int argTimeoutMilliseconds = 1000, bool argUseRetries = false)
		{
			int tmpTriesLeft = 3;
			do
			{
				if (!Monitor.TryEnter(argLock, argTimeoutMilliseconds))
				{
					if (!argUseRetries || --tmpTriesLeft == 0)
					{
						throw new ApplicationException(String.Format("Unable to lock the object: '{0}'", argObjectName));
					}
				}
				else
				{
					break;
				}
			} while (true);

			try
			{
				argAction();
			}
			finally
			{
				Monitor.Exit(argLock);
			}
		}

		public static void SyncronizeCallByLocking(this Action argAction, object argLock, int argTimeoutMilliseconds = 1000, bool argUseRetries = false)
		{
			argAction.SyncronizeCallByLocking(argLock, null, argTimeoutMilliseconds, argUseRetries);
		}
	}
}